package com.example.fwcz.config;

import com.example.fwcz.entity.user;
import com.example.fwcz.exception.BadRequestException;
import com.example.fwcz.model.vo.Result;
import com.example.fwcz.util.JacksonUtils;
import com.example.fwcz.util.JwtUtils;
import org.springframework.security.authentication.*;
import org.springframework.security.authentication.LockedException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;

import javax.servlet.FilterChain;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;

public class JwtLoginFilter extends AbstractAuthenticationProcessingFilter {
    // --- JWT 认证 ---
    protected JwtLoginFilter(String defaultFilterProcessesUrl, AuthenticationManager authenticationManager){
        super(new AntPathRequestMatcher(defaultFilterProcessesUrl));
        setAuthenticationManager(authenticationManager);
    }
    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response)
        throws AuthenticationException, IOException{
        try {
            if(!"POST".equals(request.getMethod())){
                throw new BadRequestException("请求方法错误");
            }

//            user user = JacksonUtils.readValue(request.getInputStream(),user.class);
            String username=request.getParameter("username");
            String password=request.getParameter("password");
            // --- test user infomation
            System.out.println("-------------------------------------------");
//            System.out.println("request:"+request.getInputStream());
            System.out.print("test username :"+username);
            System.out.print("test password :"+password);

            System.out.println("-------------------------------------------");

//            return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(user.getUsername(),user.getPassword()));
            return getAuthenticationManager().authenticate(new UsernamePasswordAuthenticationToken(username,password));
        }catch(BadRequestException exception){

            response.setContentType("application/json;charset=utf-8");
            Result result=Result.create(400,"非法请求");

            PrintWriter out= response.getWriter();
            out.write(JacksonUtils.writeValueAsString(result));
            out.flush();
            out.close();
        }
        return null;
    }

    @Override
    protected void successfulAuthentication(HttpServletRequest request,
                                            HttpServletResponse response,
                                            FilterChain chain,
                                            Authentication authResult) throws IOException{

        String jwt= JwtUtils.generateToken(authResult.getName(),authResult.getAuthorities());
        response.setContentType("application/json;charset=utf-8");
        user user=(user) authResult.getPrincipal();
//        user.setPassword(null);

        Map<String,Object>map=new HashMap<>();
        map.put("user",user);
        map.put("token",jwt);
        Result result=Result.ok("登录成功", map);

        PrintWriter out = response.getWriter();
        out.write(JacksonUtils.writeValueAsString(result));
        out.flush();
        out.close();
    }
    @Override
    public void unsuccessfulAuthentication(HttpServletRequest request,
                                           HttpServletResponse response,
                                           AuthenticationException exception) throws IOException{

        response.setContentType("application/json;charset=utf-8");

        String msg=exception.getMessage();
        if (exception instanceof LockedException) {
            msg = "账号被锁定";
        } else if (exception instanceof CredentialsExpiredException) {
            msg = "密码过期";
        } else if (exception instanceof AccountExpiredException) {
            msg = "账号过期";
        } else if (exception instanceof DisabledException) {
            msg = "账号被禁用";
        } else if (exception instanceof BadCredentialsException) {
            msg = "用户名或密码错误";
        }

        PrintWriter out = response.getWriter();
        out.write(JacksonUtils.writeValueAsString(Result.create(401, msg)));
        out.flush();
        out.close();
    }
}
